/*
 * ============================================================================
 *
 *       Filename:  mqtt_cliet.c
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  06/08/2020 04:54:42 PM
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  jianxi sun (jianxi), ycsunjane@gmail.com
 *   Organization:  
 *
 * ============================================================================
 */
#include "../include/mqtt_client.h"
#include "../include/common.h"
#include "../include/log.h"
#include "../include/list.h"
#include "../include/arg.h"

#include <mosquitto.h>
#include <stdio.h>
#include <stdlib.h>

#define CMDLEN  2048

void my_log_callback(struct mosquitto *mosq, void *obj, int level, const char *str)
{
	sys_debug("%s\n", str);
}

void my_connect_callback(struct mosquitto *mosq, void *obj, int result)
{
	sys_debug("connect callback: %d\n", result);
	mosquitto_subscribe(mosq, NULL, args_info.subtopic_arg, 0);
}

void my_disconnect_callback(struct mosquitto *mosq, void *obj, int rc)
{
	sys_debug("disconnect callback: %d, reconnecting\n", rc);
	while(mosquitto_reconnect(mosq) != MOSQ_ERR_SUCCESS) {
		sys_debug("reconnect failed\n");
		sleep(1);
	}
}

void my_publish_callback(struct mosquitto *mosq, void *obj, int mid)
{
	sys_debug("publish callback: %d\n", mid);
}

void my_message_callback(struct mosquitto *mosq, void *userdata,
	const struct mosquitto_message *message)
{
	if(!message->payloadlen){
		sys_debug("payload is empty\n");
		return;
	}

	char cmdbuf[CMDLEN] = {0};
	sys_debug("recv topic : %s, paload : %s, len %d\n",
		message->topic, message->payload, message->payloadlen);
	if(strncmp(message->topic, args_info.subtopic_arg,
			strlen(args_info.subtopic_arg)) == 0) {

		sprintf(cmdbuf, "%s %s 2&>/dev/null", args_info.script_arg, message->payload);
		system(cmdbuf);
	}
}

struct mymqtt * create_mqtt(const char *id, bool clean_session, void * obj)
{

	struct mymqtt *mymq = ss_malloc(sizeof(struct mymqtt));
	if(mymq == NULL) {
		sys_err("ss_malloc struct mymqtt failed\n");
		return NULL;
	}

	int ret = -1;

	mosquitto_lib_init();

	struct mosquitto *mosq = mosquitto_new(id, clean_session, NULL);
	if (!mosq) {
		sys_err("mosquitto_new failed\n");
		return NULL;
	}

	mosquitto_log_callback_set(mosq, my_log_callback);
	mosquitto_connect_callback_set(mosq, my_connect_callback);
	mosquitto_disconnect_callback_set(mosq, my_disconnect_callback);
	mosquitto_publish_callback_set(mosq, my_publish_callback);
	mosquitto_message_callback_set(mosq, my_message_callback);

	if(args_info.username_given && args_info.password_given) {
		ret = mosquitto_username_pw_set(mosq,
			args_info.username_arg, args_info.password_arg);
		if(ret != MOSQ_ERR_SUCCESS) {
			sys_err("set pw err \n");
			return NULL;
		}
	}

	ret = mosquitto_connect(mosq, args_info.host_arg,
			args_info.port_arg, args_info.keepalive_arg);

	if(ret != MOSQ_ERR_SUCCESS) {
		sys_err("connect mqtt server %s failed\n", args_info.host_arg);
		return NULL;
	} else {
		sys_debug("connect mqtt server ok\n");
	}


	ret = mosquitto_loop_start(mosq);
	if(ret != MOSQ_ERR_SUCCESS) {
		sys_debug("mqtt loop failed\n");
		return NULL;
	}

	mymq->mosq = mosq;

	return mymq;
}
